<template>
  <div class="erp-business-page">
    <el-tabs
      v-if="isMultiplePane"
      v-model="currentTab"
      class="erp-page-list-tabs"
      type="card"
      :before-leave="handleBeforeLeave"
    >
      <el-tab-pane
        v-for="(pane, paneIndex) in computedPanes"
        :key="pane.name"
        :label="pane.label"
        :name="pane.name"
        :lazy="pane.lazy"
      >
        <span slot="label">{{ pane.label }}
          <template v-if="currentTab === pane.name">
            <i
              v-if="!loading"
              class="el-icon-refresh"
              @click="refresh(paneIndex)"
            />
            <i
              v-else
              class="el-icon-loading"
            />
          </template>
        </span>
        <erp-list-page
          v-if="currentTab === pane.name"
          :key="pane.name"
          :ref="pane.name"
          :options.sync="pane.options"
          :table-props="tableProps(pane)"
          @change-options="changeOptions($event, paneIndex)"
          @emit-button="handleEmitButton($event)"
          @change-loading="handleChangeLoading"
        >
          <template
            v-if="type === 'list'"
            slot="operation-buttons"
            slot-scope="{item}"
          >
            <el-button
              v-if="item.rest && (orderStatus[item.status].name === 'REFUSE')"
              type="text"
              @click.stop="changeToDraft(item)"
            >
              转为草稿
            </el-button>
            <el-button
              v-if="shouldApprove && (orderStatus[item.status].name === 'DRAFT' || orderStatus[item.status].name === 'UNDONE')"
              :disabled="!item.myself"
              type="text"
              @click.stop="apply(item)"
            >
              提交
            </el-button>
            <el-button
              v-if="shouldApprove && (orderStatus[item.status].name === 'UNDER_REVIEW')"
              :disabled="!(item.myself)"
              type="text"
              @click.stop="revoke(item)"
            >
              撤销
            </el-button>
          </template>
        </erp-list-page>
      </el-tab-pane>
    </el-tabs>
    <erp-list-page
      v-else-if="dataOptions"
      ref="erpListPage"
      :options.sync="dataOptions"
      @change-options="changeSingleOptions"
      @emit-button="handleEmitButton($event)"
    >
      <template
        slot="operation-buttons"
        slot-scope="{item}"
      >
        <slot
          name="operation-buttons"
          :item="item"
        />
      </template>
    </erp-list-page>
    <div v-if="dynamicComponents && dynamicComponents.length > 0">
      <component
        :is="component.component"
        v-for="component in dynamicComponents"
        :key="component.path"
        ref="component.path"
        :title="component.title"
        :visible.sync="component.visible"
        :query="component.query"
        :is-new-record="component.isNewRecord"
        :is-copy="component.isCopy"
        :editable="component.editable"
        :approve-type="component.approveType"
        @refresh="refresh"
        @close="handleCloseComponent"
        @update-approve-count="handleUpdateApproveCount"
      />
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import {TabPane, Tabs} from "element-ui";
import {cloneJson, toast} from "../../../utils";
import {mergeRowMethod} from "../../../utils/erp";
import {orderStatus, shouldApproveEnum} from "./config";
import {base as request} from '@/request';
const ErpListPage = () => import('@/components/erp/ErpListPage/ErpListPage');

Vue.use(Tabs);
Vue.use(TabPane);
/**
 * 主从结构订单通用列表
 * @author maolin
 */
export default {
  name: "ErpBusinessPage",
  components: {
    ErpListPage,
  },
  props: {
    /**
     * 类型(list / approve)
     * @public
     */
    type: {
      type: String,
      default: 'list'
    },
    /**
     * 列表配置项
     * @public
     */
    options: {
      type: Object,
      default () {
        return {};
      }
    },
    /**
     * 页面关联的组件
     * @public
     */
    components: {
      type: Object,
      default () {
        return {};
      }
    },
    /**
     * 审批类型
     * @public
     */
    approveType: {
      type: Number,
      default: null,
    },
    /**
     * 主键
     * @public
     */
    primaryKey:{
      type: String,
      default: '',
    }
  },
  data() {
    return {
      dataOptions: null,
      orderStatus: orderStatus,
      currentTab: 'pane0',
      dynamicComponents: [],
      shouldApprove: false,
      loading: false,
    };
  },
  computed: {
    isMultiplePane () {
      return this.dataOptions.tabs && this.dataOptions.tabs.panes && this.dataOptions.tabs.panes.length > 0;
    },
    computedPanes () {
      let panes = cloneJson(this.dataOptions.tabs.panes);
      panes = panes.map((item, index) => {
        item.name = 'pane' + index;
        return item;
      });
      return panes;
    },
    tableProps (pane) {
      return function (pane) {
        return {
          spanMethod: this.mergeRowMethod,
          border: true,
        };
      };
    }
  },
  watch: {
    type: {
      handler (type) {
        if (type === 'list') {
          this.getApproveStatus();
        }
      },
      immediate: true
    },
    approveType: {
      handler (type) {
      },
      immediate: true
    },
    options: {
      handler (opt) {
        this.dataOptions = opt;
      },
      immediate: true
    }
  },
  created() {
    this.generateDynamicComponents();
  },
  mounted() {
  },
  methods: {
    /**
     * 获取当前订单列表是否需要进行审核
     * @public
     */
    getApproveStatus () {
      request.post('/activitiController/activitiUpdateInit', {id: this.approveType})
        .then(res => {
          const data = res.data.bindDataItem;
          let shouldApprove = !!(data.status == shouldApproveEnum['YES'].value);
          this.shouldApprove = shouldApprove;
          this.$store.dispatch('approve/updateStatus', {approveType: this.approveType, status: shouldApprove});
        });
    },
    /**
     * 改变表格loading状态
     * @param {boolean} loading 是否处于加载状态
     * @public
     */
    handleChangeLoading (loading) {
      this.loading = loading;
    },
    /**
     * 生成动态组件
     * @public
     */
    generateDynamicComponents () {
      const components = this.components;
      let dynamicComponents = [];
      if (components) {
        for (let i in components) {
          let path = components[i].path;
          components[i].component = this.getView(path);
          components[i].visible = false;
          components[i].approveType = this.approveType;
          components[i].mode = i;
          dynamicComponents.push(components[i]);
        }
      }
      this.dynamicComponents = dynamicComponents;
    },
    /**
     * 通过路径获取视图组件
     * @param {string} path 以src/views为根路径的组件路径
     * @public
     */
    getView (path) {
      return resolve => {
        require.ensure([], () =>
          resolve(require(`@/views${path}.vue`)));
      };
    },
    /**
     * 切换列表tab
     * @public
     */
    handleBeforeLeave (vModel) {
      let panes = this.computedPanes;
      let pane = null;
      if (panes && panes.length > 0) {
        for (let i in panes) {
          if (vModel === panes[i].name) {
            pane = panes[i];
            break;
          }
        }
        if (pane.type === 'link') {
          let path = this.getPathFromRouter(pane.options);
          this.$router.push(path);
          return false;
        }
        return true;
      }
    },
    /**
     * 刷新列表
     * @public
     */
    refresh () {
      if (this.isMultiplePane) {
        let index = this.currentTab;
        this.$refs[index][0].getList();
      } else {
        this.$refs.erpListPage.getList();
      }
    },
    /**
     * 合并行数据
     * @public
     */
    mergeRowMethod ({ row, _rowIndex, column, visibleData }) {
      let options = null;
      for (let i in this.computedPanes) {
        if (this.computedPanes[i].name === this.currentTab) {
          options = this.computedPanes[i].options;
        }
      }
      const uniqueField = options.table && options.table.mergeRowConfig ? options.table.mergeRowConfig.uniqueField : null;
      const extraFields = options.table && options.table.mergeRowConfig ? options.table.mergeRowConfig.extraFields : [];
      if (!uniqueField) {
        return null;
      }
      return mergeRowMethod({ row, _rowIndex, column, visibleData }, uniqueField, extraFields);
    },
    /**
     * 改变某一个tab的列表选项
     * @public
     */
    changeOptions (opt, paneIndex) {
      let options = this.dataOptions;
      let pane = options && options.tabs && options.tabs.panes && options.tabs.panes[paneIndex] ? options.tabs.panes[paneIndex] : null;
      if (pane) {
        options.tabs.panes[paneIndex].options = opt;
        this.dataOptions = options;
      }
    },
    /**
     * 改变单个列表的选项
     * @public
     */
    changeSingleOptions (opt) {
      this.dataOptions = opt;
    },
    /**
     * 显示动态组件(添加,编辑,详情等表单)
     * @param {number} key 组件的key
     * @param {object} item 组件的配置对象
     * @public
     */
    showModal (key, item) {
      this.dynamicComponents = this.dynamicComponents.map(obj => {
        obj.visible = obj.mode === key;
        let query = {};
        if ((obj.needId === undefined || obj.needId !== false) && item) {
          query = {
            id: item[this.primaryKey]
          };
        }
        if (this.type === 'approve') {
          query.taskId = item.taskId;
          query.activiItemId = item.activiItemId;
          if (item.materialTyped !== undefined) {
            query.materialType = item.materialTyped;
          } else {
            query.materialType = item.materialType;
          }
        }
        obj.query = Object.assign(obj.query || {}, query);
        return obj;
      });
    },
    /**
     * 提交申请
     * @param {object} item 列表中的某一行对象
     * @public
     */
    apply (item) {
      this.$msgbox({
        title: '提示',
        message: '确定提交申请吗？',
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showCancelButton: true,
        type: 'warning'
      }).then(() => {
        let loading = toast({
          message: "正在提交...",
          type: "info",
          iconClass: "el-icon-loading",
          duration: 10000
        });
        request.post('/activitiController/application', {
          id: item[this.primaryKey],
          type: this.approveType
        })
          .then( res => {
            loading.close();
            toast({
              message: "申请提交成功",
              type: 'success'
            });
            this.refresh();
          })
          .catch(() => {
            loading.close();
          })
          .finally(() => {});
      }).catch(() => {
      });

    },
    /**
     * 将订单状态转为草稿
     * @param {object} item 列表中的某一行对象
     * @public
     */
    changeToDraft (item) {
      this.$msgbox({
        title: '提示',
        message: '确定要转为草稿吗？',
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showCancelButton: true,
        type: 'warning'
      }).then(() => {
        let loading = toast({
          message: "正在提交...",
          type: "info",
          iconClass: "el-icon-loading",
          duration: 10000
        });
        request.post('/activitiController/handleRest', {
          id: item[this.primaryKey],
          activiItemId: item.activiItemId,
          type: this.approveType
        })
          .then( res => {
            loading.close();
            toast({
              message: "转换草稿成功",
              type: 'success'
            });
            this.refresh();
          })
          .catch(() => {
            loading.close();
          })
          .finally(() => {});
      }).catch(() => {
      });
    },
    /**
     * 将已申请的订单撤销申请
     * @param {object} item 列表中的某一行对象
     * @public
     */
    revoke (item) {
      this.$msgbox({
        title: '提示',
        message: '确定撤销申请吗？',
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showCancelButton: true,
        type: 'warning'
      }).then(() => {
        let loading = toast({
          message: "正在提交...",
          type: "info",
          iconClass: "el-icon-loading",
          duration: 10000
        });
        request.post('/activitiController/handleRevoke', {
          id: item[this.primaryKey],
          activiItemId: item.activiItemId,
          type: this.approveType
        })
          .then( res => {
            loading.close();
            toast({
              message: "申请已撤销",
              type: 'success'
            });
            this.refresh();
          })
          .catch(() => {
            loading.close();
          })
          .finally(() => {});
      }).catch(() => {
      });
    },
    /**
     * 点击按钮显示对应的组件
     * @param {object} button  按钮对象
     * @param {object} row  行数据
     * @public
     */
    handleEmitButton ({button, row}) {
      const componentKey = button.componentKey;
      try{
        this.showModal(componentKey, row);
      } catch (e) {
        console.log('请配置按钮的componentKey');
      }
    },
    /**
     * 隐藏所有的组件弹窗
     * @public
     */
    handleCloseComponent () {
      this.dynamicComponents = this.dynamicComponents.map(item => {
        item.visible = false;
        return item;
      });
    },
    /**
     * 更新审批数量
     * @public
     */
    handleUpdateApproveCount () {
      this.$emit('update-approve-count');
    }
  },
};
</script>

<style lang="scss" scoped>
.erp-business-page{
    height: 100%;
    background-color: #fff;
}
</style>
